package com.cfweb.controller.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javassist.expr.NewArray;

import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cfweb.api.UserApi;
import com.cfweb.controller.LoginHandler;
import com.cfweb.dao.AuthUserMapper;
import com.cfweb.dao.CfUserMapper;
import com.cfweb.domain.AuthUser;
import com.cfweb.domain.AuthUserExample;
import com.cfweb.domain.CfUser;
import com.cfweb.domain.CfUserExample;
import com.cfweb.util.ExtJSResponse;
import com.cfweb.util.StringUtil;

/**
 * 
 * @author dt
 * 
 */
@Service
@Path("/user")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserManagement {

	Logger logger = Logger.getLogger(UserManagement.class);

	@Autowired
	private HttpSession session;
	@Autowired
	private CfUserMapper cuMapper;
	@Autowired
	private AuthUserMapper auMapper;

	/**
     * list all of users
     * @return list
     */
	@Path("/listall")
	@GET
	public ExtJSResponse listall() {
		List<CfUser> users = null;
		CfUserExample example = new CfUserExample();
		example.createCriteria().andIdIsNotNull();
		users = cuMapper.selectByExample(example);
		return ExtJSResponse.successResWithData(users);
	}

	/**
     * add a user
     * @param userName
     * @param userPass
     * @return success or error
     */
	@Path("/add")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse add(@FormParam("userName") String userName,
			@FormParam("userPass") String userPass) throws Exception {
		CfUser user = new CfUser();
		if (UserApi.create_user(session, userName, userPass)) {
			user.setUserName(userName);
			user.setUserPass(userPass);
			user.setUserIsadmin(0);

			String uuid = UserApi.get_user_id(session, userName);
			user.setUuid(uuid);
			cuMapper.insert(user);
			return ExtJSResponse.successRes();
		}
		return ExtJSResponse.errorRes();
	}

	/**
     * delete a user
     * @param userName
     * @return success or error
     */
	@Path("/delete")
	@GET
	public ExtJSResponse delete(@QueryParam("userName") String userName)
			throws Exception {
		if (UserApi.delete_user(session, userName)) {
			CfUserExample example = new CfUserExample();
			example.createCriteria().andUserNameEqualTo(userName);
			cuMapper.deleteByExample(example);
			return ExtJSResponse.successRes();
		}
		return ExtJSResponse.errorRes();
	}
	
	/**
     * list users in the org
     * @param orgName
     * @param roleType
     * @return list<user>
     */
	@Path("/orgUser")
	@GET
	public ExtJSResponse orgUser(@QueryParam("orgName") String orgName,
			@QueryParam("roleType") String roleType) {
		AuthUserExample auEx = new AuthUserExample();
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andIdIsNotNull();
		List<CfUser> lcu = cuMapper.selectByExample(cuEx);
		List<Map<String, Object>> luser = new ArrayList<Map<String, Object>>();
		for (CfUser cu : lcu) {
			Map<String, Object> tmp = new HashMap<String, Object>();
			auEx.clear();
			auEx.createCriteria().andAuthTypeEqualTo(roleType)
					.andOrgNameEqualTo(orgName).andUserIdEqualTo(cu.getId());
			if (auMapper.selectByExample(auEx).isEmpty()) {
			    tmp.put("userRole", 0);
			} else {
			    tmp.put("userRole", 1);
			}
			tmp.put("userName", cu.getUserName());
			luser.add(tmp);
		}
		return ExtJSResponse.successResWithData(luser);
	}

	/**
     * list orgRole of current user
     * @param orgName
     * @return list<role>
     */
	@Path("/currentuserOrgRole")
	@GET
	public ExtJSResponse userOrgRole(@QueryParam("orgName") String orgName) {
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andUserNameEqualTo(
				(String) session.getAttribute(LoginHandler.USERNAME));
		int userId = cuMapper.selectByExample(cuEx).get(0).getId();
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andOrgNameEqualTo(orgName)
				.andUserIdEqualTo(userId);
		List<AuthUser> lau = auMapper.selectByExample(auEx);
		return ExtJSResponse.successResWithData(lau);
	}

	/**
     * list role of current user
     * @return list<role>
     */
	@Path("/currentuserRole")
	@GET
	public ExtJSResponse getCurrentuserRole() {
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andUserNameEqualTo(
				(String) session.getAttribute(LoginHandler.USERNAME));
		int userId = cuMapper.selectByExample(cuEx).get(0).getId();
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andUserIdEqualTo(userId);
		List<AuthUser> lau = auMapper.selectByExample(auEx);
		return ExtJSResponse.successResWithData(lau);
	}

	/**
     * list OrgSpaceRole of current user
     * @param orgName
     * @return list<role>
     */
	@Path("/currentuserOrgSpace")
	@GET
	public ExtJSResponse getCurrentuserOrgSpace() {
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andUserNameEqualTo(
				(String) session.getAttribute(LoginHandler.USERNAME));
		List<String> lau = new ArrayList<String>();
		lau.add((String) session.getAttribute(LoginHandler.ORG));
		lau.add((String) session.getAttribute(LoginHandler.SPACE));
		return ExtJSResponse.successResWithData(lau);
	}

	/**
     * list OrgRole by userId in the org
     * @param orgName
     * @param userId
     * @return list<userRole>
     */
	@Path("/userOrgRole")
	@GET
	public ExtJSResponse userOrgRole(@QueryParam("orgName") String orgName,
			@QueryParam("userId") String userId) {
		List<String> response = new ArrayList<>();
		AuthUserExample auEx = new AuthUserExample();
		if (userId == null || "".equals(userId)) {
		    userId = session.getAttribute("userid").toString();
		}
		auEx.createCriteria().andOrgNameEqualTo(orgName)
				.andUserIdEqualTo(Integer.valueOf(userId)).andSpaceNameIsNull();
		List<AuthUser> lau = auMapper.selectByExample(auEx);
		for (AuthUser user : lau) {
			response.add(user.getAuthType());
		}
		return ExtJSResponse.successResWithData(response);
	}
	
	/**
     * list SpaceRole by userId in the org
     * @param spaceName
     * @param userId
     * @return list<userRole>
     */
	@Path("/userSpaceRole")
	@GET
	public ExtJSResponse userSpaceRole(
			@QueryParam("spaceName") String spaceName,
			@QueryParam("userId") String userId) {
		List<String> response = new ArrayList<>();
		AuthUserExample auEx = new AuthUserExample();
		if (userId == null || "".equals(userId)) {
		    userId = session.getAttribute("userid").toString();
		}
		auEx.createCriteria().andUserIdEqualTo(Integer.valueOf(userId))
				.andSpaceNameEqualTo(spaceName);
		List<AuthUser> lau = auMapper.selectByExample(auEx);
		for (AuthUser user : lau) {
			response.add(user.getAuthType());
		}
		return ExtJSResponse.successResWithData(response);
	}

	/**
     * list users in the space of the org
     * @param spaceName
     * @param orgName
     * @return list<spaceUser>
     */
	@Path("/spaceUser")
	@GET
	public ExtJSResponse spaceUser(@QueryParam("orgName") String orgName,
			@QueryParam("spaceName") String spaceName) {
		AuthUserExample example = new AuthUserExample();
		example.createCriteria().andOrgNameEqualTo(orgName)
				.andSpaceNameEqualTo(spaceName);
		List<AuthUser> lau = auMapper.selectByExample(example);
		List<String> luser = new ArrayList<String>();
		for (AuthUser au : lau) {
			String userName = cuMapper.selectByPrimaryKey(au.getUserId())
					.getUserName();
			if (!luser.contains(userName)) {
			    luser.add(userName);
			}
		}
		return ExtJSResponse.successResWithData(luser);
	}

	/**
     * list users not in the space of the org
     * @param spaceName
     * @param orgName
     * @param roleType
     * @return list<notSpaceUser>
     */
	@Path("/notSpaceUser")
	@GET
	public ExtJSResponse notSpaceUser(@QueryParam("orgName") String orgName,
			@QueryParam("spaceName") String spaceName,
			@QueryParam("roleType") String roleType) {
		AuthUserExample example = new AuthUserExample();
		example.createCriteria().andOrgNameEqualTo(orgName)
				.andSpaceNameEqualTo(spaceName).andAuthTypeEqualTo(roleType);
		List<AuthUser> lau = auMapper.selectByExample(example);
		List<String> luser = new ArrayList<String>();
		for (AuthUser au : lau) {
			String userName = cuMapper.selectByPrimaryKey(au.getUserId())
					.getUserName();
			if (!luser.contains(userName)) {
			    luser.add(userName);
			}
		}
		// System.out.println(luser);
		CfUserExample cuEx = new CfUserExample();
		if (!luser.isEmpty()) {
			cuEx.createCriteria().andUserNameNotIn(luser);
			return ExtJSResponse.successResWithData(cuMapper
					.selectByExample(cuEx));
		} else {
			cuEx.createCriteria().andIdIsNotNull();
		}
		return ExtJSResponse.successResWithData(cuMapper.selectByExample(cuEx));
	}

	/**
     * set roles in the org
     * @param userName
     * @param orgName
     * @param roleType
     * @return list<notSpaceUser>
     */
	@Path("/setOrgRole")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse setOrgRole(@FormParam("orgName") String orgName,
			@FormParam("userName") String userName,
			@FormParam("roleType") String roleType) throws Exception {
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andUserNameEqualTo(userName);
		int userId = cuMapper.selectByExample(cuEx).get(0).getId();
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andOrgNameEqualTo(orgName).andSpaceNameIsNull()
				.andUserIdEqualTo(userId).andAuthTypeEqualTo(roleType);
		if (auMapper.selectByExample(auEx).size() == 0) {
			if (UserApi.set_org_role(session, userName, orgName, roleType)) {
				AuthUser au = new AuthUser();
				au.setAuthType(roleType);
				au.setOrgName(orgName);
				au.setUserId(userId);
				auMapper.insert(au);
				return ExtJSResponse.successRes();
			}
		}
		return ExtJSResponse.errorRes();
	}

	/**
     * unset roles in the org
     * @param userName
     * @param orgName
     * @param roleType
     * @return list<notSpaceUser>
     */
	@Path("/unsetOrgRole")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse unsetOrgRole(@FormParam("orgName") String orgName,
			@FormParam("userName") String userName,
			@FormParam("roleType") String roleType) throws Exception {
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andUserNameEqualTo(userName);
		int userId = cuMapper.selectByExample(cuEx).get(0).getId();
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andOrgNameEqualTo(orgName).andSpaceNameIsNull()
				.andUserIdEqualTo(userId).andAuthTypeEqualTo(roleType);
		if (auMapper.selectByExample(auEx).size() > 0) {
			if (UserApi.unset_org_role(session, userName, orgName, roleType)) {
				auMapper.deleteByExample(auEx);
				return ExtJSResponse.successRes();
			}
		}
		return ExtJSResponse.errorRes();
	}

	/**
     * set space of role in the org
     * @param userName
     * @param orgName
     * @param spaceName
     * @param roleType
     * @return list<notSpaceUser>
     */
	@Path("/setSpaceRole")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse setSpaceRole(@FormParam("orgName") String orgName,
			@FormParam("spaceName") String spaceName,
			@FormParam("userName") String userName,
			@FormParam("roleType") String roleType) throws Exception {
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andUserNameEqualTo(userName);
		int userId = cuMapper.selectByExample(cuEx).get(0).getId();
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andOrgNameEqualTo(orgName)
				.andSpaceNameEqualTo(spaceName).andUserIdEqualTo(userId)
				.andAuthTypeEqualTo(roleType);
		if (auMapper.selectByExample(auEx).size() == 0) {
			if (UserApi.set_space_role(session, userName, orgName, spaceName,
					roleType)) {
				AuthUser au = new AuthUser();
				au.setAuthType(roleType);
				au.setOrgName(orgName);
				au.setSpaceName(spaceName);
				au.setUserId(userId);
				auMapper.insert(au);
				CfUser cu = cuMapper.selectByExample(cuEx).get(0);
				System.out.println("haha");
				System.out.println(cu.getLastSpace());
				if (cu.getLastSpace().isEmpty() || cu.getLastSpace() == null) {
					cu.setLastOrg(orgName);
					cu.setLastSpace(spaceName);
					cuMapper.updateByPrimaryKey(cu);
				}
				System.out.println("habuha");
				return ExtJSResponse.successRes();
			}
		}
		return ExtJSResponse.errorRes();
	}

	/**
     * unset space of role in the org
     * @param userName
     * @param orgName
     * @param spaceName
     * @param roleType
     * @return list<notSpaceUser>
     */
	@Path("/unsetSpaceRole")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse unsetSpaceRole(@FormParam("orgName") String orgName,
			@FormParam("spaceName") String spaceName,
			@FormParam("userName") String userName,
			@FormParam("roleType") String roleType) throws Exception {
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andUserNameEqualTo(userName);
		int userId = cuMapper.selectByExample(cuEx).get(0).getId();
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andOrgNameEqualTo(orgName)
				.andSpaceNameEqualTo(spaceName).andUserIdEqualTo(userId)
				.andAuthTypeEqualTo(roleType);
		if (auMapper.selectByExample(auEx).size() > 0) {
			if (UserApi.unset_space_role(session, userName, orgName, spaceName,
					roleType)) {
				auMapper.deleteByExample(auEx);
				cuEx.clear();
				cuEx.createCriteria().andUserNameEqualTo(userName)
						.andLastOrgEqualTo(orgName)
						.andLastSpaceEqualTo(spaceName);
				List<CfUser> lcu = cuMapper.selectByExample(cuEx);
				if (lcu.size() > 0) {
					CfUser cu = lcu.get(0);
					auEx.clear();
					auEx.createCriteria().andUserIdEqualTo(userId)
							.andSpaceNameIsNotNull();
					if (auMapper.selectByExample(auEx).size() > 0) {
						AuthUser au = auMapper.selectByExample(auEx).get(0);
						cu.setLastOrg(au.getOrgName());
						cu.setLastSpace(au.getSpaceName());
					} else {
						cu.setLastOrg(null);
						cu.setLastSpace(null);
					}
					cuMapper.updateByPrimaryKey(cu);
				}
				return ExtJSResponse.successRes();
			}
		}
		return ExtJSResponse.errorRes();
	}

	/**
     * check user who is admin or not
     * @return true or false
     */
	@Path("/isAdmin")
	@GET
	public ExtJSResponse isAdmin() {
		String userName = (String) session.getAttribute(LoginHandler.USERNAME);
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andUserNameEqualTo(userName);
		int isAdmin = cuMapper.selectByExample(cuEx).get(0).getUserIsadmin();
		return ExtJSResponse.successResWithKeyValue("isAdmin", isAdmin);
	}

	/**
     * update role in the org or space
     * @param userId
     * @param orgName
     * @param aorgRoles
     * @param dorgRoles
     * @param spaceName
     * @param aspaceRoles
     * @param dspaceRoles
     * @return success or error
     */
	@POST
	@Path("/updateUserRole")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse updateUserRole(@FormParam("userId") String userId,
			@FormParam("orgName") String orgName,
			@FormParam("aorgRoles") String[] aorgRoles,
			@FormParam("dorgRoles") String[] dorgRoles,
			@FormParam("spaceName") String spaceName,
			@FormParam("aspaceRoles") String[] aspaceRoles,
			@FormParam("dspaceRoles") String[] dspaceRoles) throws Exception {
		Integer userid = Integer.valueOf(userId);
		CfUser user = cuMapper.selectByPrimaryKey(userid);
		// 解邦权限
		AuthUserExample auEx = new AuthUserExample();
		CfUserExample cuEx = new CfUserExample();
		for (String role : dorgRoles) {
			auEx.clear();
			auEx.createCriteria().andOrgNameEqualTo(orgName)
					.andSpaceNameIsNull().andUserIdEqualTo(userid)
					.andAuthTypeEqualTo(role);
			if (auMapper.selectByExample(auEx).size() > 0) {
				if (UserApi.unset_org_role(session, user.getUserName(),
						orgName, role)) {
					auMapper.deleteByExample(auEx);
				}
			}
		}
		// 增加org权限
		for (String role : aorgRoles) {
			if (UserApi
					.set_org_role(session, user.getUserName(), orgName, role)) {
				AuthUser au = new AuthUser();
				au.setAuthType(role);
				au.setOrgName(orgName);
				au.setUserId(userid);
				auMapper.insert(au);
			}
		}

		// 解邦space权限
		for (String role : dspaceRoles) {
			auEx.clear();
			auEx.createCriteria().andOrgNameEqualTo(orgName)
					.andSpaceNameEqualTo(spaceName).andUserIdEqualTo(userid)
					.andAuthTypeEqualTo(role);
			if (auMapper.selectByExample(auEx).size() > 0) {
				if (UserApi.unset_space_role(session, user.getUserName(),
						orgName, spaceName, role)) {
					auMapper.deleteByExample(auEx);
					System.out.println("deleteSpaceRole finished!");
				}
			}
		}

		// 增加space权限
		for (String role : aspaceRoles) {
			auEx.clear();
			auEx.createCriteria().andOrgNameEqualTo(orgName)
					.andSpaceNameEqualTo(spaceName).andUserIdEqualTo(userid)
					.andAuthTypeEqualTo(role);
			cuEx.clear();
			cuEx.createCriteria().andUserNameEqualTo(user.getUserName());
			if (auMapper.selectByExample(auEx).size() == 0) {
				if (UserApi.set_space_role(session, user.getUserName(),
						orgName, spaceName, role)) {
					AuthUser au = new AuthUser();
					au.setAuthType(role);
					au.setOrgName(orgName);
					au.setSpaceName(spaceName);
					au.setUserId(user.getId());
					auMapper.insert(au);
				}
			}
		}
		
		//设置用户登录space和org
		
		if(StringUtil.isEmpty(orgName)&&StringUtil.isEmpty(spaceName)){
			return ExtJSResponse.successRes();
		}
		
		cuEx.createCriteria()
		.andUserNameEqualTo(user.getUserName());
		List<CfUser> lcu = cuMapper.selectByExample(cuEx);
		CfUser cu=null;
		if(lcu.size()>0){
			cu = lcu.get(0);
		}	
		if((aorgRoles.length>0||dorgRoles.length>0)&&(aspaceRoles.length==0&&dspaceRoles.length==0)){
			if (cu!=null&&(StringUtil.isEmpty(cu.getLastOrg())||orgName.equals(cu.getLastOrg()))) {
				auEx.clear();
				auEx.createCriteria().andUserIdEqualTo(userid)
						.andOrgNameEqualTo(orgName);
				if (auMapper.selectByExample(auEx).size() <=0) {
					auEx.clear();
					auEx.createCriteria().andUserIdEqualTo(userid);
					if(auMapper.selectByExample(auEx).size() > 0){
						AuthUser authUser=auMapper.selectByExample(auEx).get(0);
						cu.setLastOrg(authUser.getOrgName());
						cu.setLastSpace(authUser.getSpaceName());
					}else{
						cu.setLastOrg(null);
						cu.setLastSpace(null);
					}
				}else{
					cu.setLastOrg(orgName);
				}
				cuMapper.updateByPrimaryKey(cu);
			}
		}
		
		if (aspaceRoles.length>0||dspaceRoles.length>0) {
			if (cu!=null&&(StringUtil.isEmpty(cu.getLastSpace())||spaceName.equals(cu.getLastSpace()))){
				auEx.clear();
				auEx.createCriteria().andUserIdEqualTo(userid).andOrgNameEqualTo(orgName).andSpaceNameEqualTo(spaceName);
				if (auMapper.selectByExample(auEx).size()< 0){
					auEx.clear();
					auEx.createCriteria().andUserIdEqualTo(userid);
					List<AuthUser> auths=auMapper.selectByExample(auEx);
					if(auths.size()>0){
						cu.setLastOrg(auths.get(auths.size()-1).getOrgName());
						cu.setLastOrg(auths.get(auths.size()-1).getSpaceName());
					}else{
						cu.setLastOrg(null);
						cu.setLastSpace(null);
					}
				}else{
					cu.setLastOrg(orgName);
					cu.setLastSpace(spaceName);
				}
			}
			cuMapper.updateByPrimaryKey(cu);
		}
		return ExtJSResponse.successRes();
	}

	/**
     * check userName for the same
     * @param userName
     * @return true or false
     */
	@Path("/checkUserName")
	@GET
	public ExtJSResponse checkUserName(
			@QueryParam("userName") final String userName) throws Exception {
		if (!UserApi.get_user_id(session, userName).isEmpty()) {
			return ExtJSResponse.successResWithData(false);
		}
		return ExtJSResponse.successResWithData(true);
	}
	
	@Path("/changePasswd")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	@POST
	public ExtJSResponse changeCurrentUserPassword(@FormParam("oldPassword")String oldPassowrd,@FormParam("password")String newPassword) throws Exception{
		String username=(String) session.getAttribute(LoginHandler.USERNAME);
		CfUserExample example = new CfUserExample();
		example.createCriteria().andUserNameEqualTo(username)
				.andUserPassEqualTo(oldPassowrd);
		List<CfUser> cfuserList = cuMapper.selectByExample(example);
		if(cfuserList.size()<=0){
			return ExtJSResponse.errorResWithMsg("passwordError");
		}
		String uguid=UserApi.get_user_id(session, username);
		Map<String, Object> params=new HashMap<>();
		params.put("password",newPassword);
		params.put("oldPassword", oldPassowrd);	
		UserApi.updateUserPassword(session, uguid, params);
		CfUser user=cfuserList.get(0);
		user.setUuid(uguid);
		user.setUserPass(newPassword);
		cuMapper.updateByPrimaryKeySelective(user);
		return ExtJSResponse.successResWithData(true);
	}

}
